using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AgvLiftComponent : IAgvBaseLift
{
    public float Time_To_Lift;
    public float liftSpeed;

    protected Transform lift;


    protected LiftBehaviour liftBehaviour;
    protected LiftBehaviourParam liftBehaviourParam;

    protected List<float> TargetHeightList;

    protected float startHeight, endHeight;
    float liftingTime;

    int startAccelerateCount = 2;

    bool allowAccelerate = false;

    public AgvLiftComponent(Transform lift, LiftBehaviour liftBehaviour)
    {
        this.lift = lift;
        this.liftBehaviour = liftBehaviour;

        TargetHeightList = new();
    }

    public virtual void Update()
    {
        if(TargetHeightList.Count > 0)
        {
            LiftPerTick();
            ReachTargetHeight();
        }
    }

    bool bIsInit = false;
    public void SetTargetHeight(float height)
    {
        if (!bIsInit)
        {
            Init(height / 1000);
        }
        StoreHeight(height / 1000);
    }

    protected virtual void Init(float height)
    {
        //height /= 1000;
        lift.localPosition = new Vector3(lift.localPosition.x, height, lift.localPosition.z);

        bIsInit = true;
    }

    public void LiftPerTick()
    {
        if (TargetHeightList.Count > 0 && lift.localPosition.y != TargetHeightList[0])
        {
            //endHeight = TargetHeightList[0];

            liftBehaviour.LiftUp(new LiftBehaviourParam(Lift: lift, current: startHeight, end: endHeight, routeTime: Time_To_Lift, timer: liftingTime, liftSpeed: liftSpeed));

            liftingTime += Time.deltaTime;

            if (allowAccelerate && TargetHeightList.Count > startAccelerateCount)
            {
                liftingTime++;
            }
        }
    }

    public void ReachTargetHeight()
    {
        if (Mathf.Abs(lift.localPosition.y - TargetHeightList[0]) < 0.001f)
        {
            RefreshHeight();
        }
    }
    protected virtual void RefreshHeight()
    {
        liftingTime = 0;
        startHeight = lift.localPosition.y;

        TargetHeightList.RemoveAt(0);

        if (TargetHeightList.Count > 0)
        {
            //endHeight = TargetHeightList[0];
            SetNextTargetHeight(TargetHeightList[0]);
        }
        else
        {
            //endHeight = startHeight;
            //SetNextTargetHeight(startHeight);
        }
    }
    public virtual void StoreHeight(float targetHeight)
    {
        if (TargetHeightList.Count == 0)
        {
            if (targetHeight != startHeight && Mathf.Abs(targetHeight - startHeight) > 0.01f)
            {
                TargetHeightList.Add(targetHeight);
                SetNextTargetHeight(targetHeight);
            }
        }
        else if (targetHeight != TargetHeightList[^1] && Mathf.Abs(targetHeight - TargetHeightList[^1]) > 0.01f)
        {
            TargetHeightList.Add(targetHeight);
        }
    }
    protected virtual void SetNextTargetHeight(float targetHeight)
    {
        endHeight = targetHeight;
    }
    public float GetLiftingSpeed()
    {
        if (liftSpeed != 0)
            return liftSpeed;
        return liftBehaviour.LiftingSpeed;
    }
}


public class LiftComponent_ForkLift : AgvLiftComponent
{
    LiftingParts LiftingParts;
    public LiftComponent_ForkLift(Transform lift, LiftBehaviour liftBehaviour, LiftingParts liftingParts) : base(lift, liftBehaviour)
    {
        LiftingParts = liftingParts;
    }

    /*public override void GetTargetHeight(float height)
    {
        if (!bIsInit)
        {
            Init(height);
        }
        StoreHeight(height / 1000);

    }*/

    public override void Update()
    {
        base.Update();
        if (TargetHeightList.Count > 0)
        {
            if (TargetHeightList[0] >= 1.5f && LiftingParts != null)
            {
                LiftingParts.target = TargetHeightList[0] + 1f;
                if (LiftingParts.bIsMovingDown == true)
                {
                    LiftingParts.LiftDown(TargetHeightList[0]);
                }
                else
                {
                    LiftingParts.LiftUp(lift.transform.localPosition.y * lift.transform.localScale.y - 1.5f);
                }
            }
            else if (LiftingParts != null && LiftingParts.bIsMovingDown == true)
            {
                LiftingParts.LiftDown();
            }
        }
    }

    public override void StoreHeight(float targetHeight)
    {
        base.StoreHeight(targetHeight);
    }

    protected override void SetNextTargetHeight(float targetHeight)
    {
        base.SetNextTargetHeight(targetHeight);
        if (targetHeight * lift.transform.localScale.y < lift.transform.localPosition.y)
            LiftingParts.bIsMovingDown = true;
    }
    protected override void Init(float height)
    {
        base.Init(height);
        if (LiftingParts != null)
        {
            LiftingParts.target = height + 1f;
            LiftingParts.LiftToTarget(lift.transform.localPosition.y);
        }
    }
}